﻿using System;
using System.Collections.Generic;
using System.Threading;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.IO;
using WPFExcelReport;
using WPFExcelReport.Helpers;
using System.Data;
using System.Linq;
using ReflectionStudio.Core.Events;
namespace WPFExcelReport
{

    /// <summary>
    /// 与客户端的 连接通信类(包含了一个 与客户端 通信的 套接字，和线程)
    /// </summary>
    public class AMClient
    {
        private Dictionary<string, object> _MachinesLib;
        public Dictionary<string, object> MachinesLib
        {
            get
            {
                if (_MachinesLib == null)
                    _MachinesLib = new Dictionary<string, object>();
                return _MachinesLib;
            }

        }
        public ApplicationBase app
        {
            get
            {
                return ApplicationBase.Instance;
            }
        }
        public Dictionary<string, object> ENVMAIN
        {
            get
            {
                return app.ENVMAIN(app.ServiceUri);
            }
        }
        public VICC_ZLAN VZL
        {
            get
            {
                if (!ENVMAIN.ContainsKey("VZL"))
                    ENVMAIN["VZL"] = new VICC_ZLAN();
                return (VICC_ZLAN)ENVMAIN["VZL"];
            }
        }
        public VAMEINST VAME
        {
            get
            {
                if (!ENVMAIN.ContainsKey("VAME"))
                    ENVMAIN["VAME"] = new VAMEINST();
                return (VAMEINST)ENVMAIN["VAME"];
            }
        }

        private Socket _clientSocket;

        public Socket ClientSocket
        {
            get
            {
                return _clientSocket;
            }
        }
        public DataTable TBZLAM
        {
            get;
            set;
        }
        public string DEVTYP
        {
            get;
            set;
        }


        public string PLCIP
        {
            get;
            set;
        }
        bool _IsPortReaday = false;
        public bool IsPortReaday
        {
            get
            {
                return _IsPortReaday;
            }
            set
            {
                _IsPortReaday = value;
            }
        }
        public IPEndPoint EndPoint
        {
            get;
            set;
        }
        public Thread receiveThread;
        public string ClientID = "";
        #region 构造函数
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sokMsg">通信套接字</param>
        /// <param name="dgShowMsg">向主窗体文本框显示消息的方法委托</param>
        public AMClient(bool IsDBA = false)
        {
            try
            {
                if (ClientSocket == null)
                {

                }

                _clientSocket = new Socket(
                   app.SockeSerIP.AddressFamily,// Specifies the addressing scheme 
                   SocketType.Stream,   // The type of socket  
                   ProtocolType.Tcp     // Specifies the protocols  
                   );
                //产生本地端口号
                //修改设备此时用于沟通的监控端口号 
                //如果有多个监听的位置呢？改如何处理？只有一个主监听，其他的重新开发客户端，仅仅从数据库获取数据
                EndPoint = new IPEndPoint(app.SockeSerIP, 25007);
                ClientSocket.NoDelay = false;   // Using the Nagle algorithm  
                // Establishes a connection to a remote host 
                ClientSocket.Connect(EndPoint);//连接到服务器 
                receiveThread = new Thread(ReceiveMessage);
                receiveThread.Name = Guid.NewGuid().ToString();
                receiveThread.IsBackground = true;
                receiveThread.Start();
            }
            catch (Exception ex)
            {
                Helpers.LogHelper.error(ex.StackTrace + ex.Message);
            }
        }

        public bool GetDevTyp()
        {
            bool IsLogged = false;
            string filter = "LOCALIP='" + PLCIP + "'";
            DataRow[] rows = TBZLAM.Select(filter);
            if (rows.Length > 0)
            {
                IsLogged = true;
                DEVTYP = rows[0]["DEVTYP"].ToString().Trim();
            }
            else
            {
                DEVTYP = "TBA";
            }
            return IsLogged;
        }
        #endregion
        long lastticks = -1;
        bool isRec = true;
        #region 02负责监听服务器发送来的消息 
        public delegate void SetFunctionDelegate(UIAM uiam, string id, string vu);
        private void ReceiveMessage()
        {
            byte[] SocketResult = new byte[1024];
            while (true)
            {
                try
                {
                    //通过clientSocket接收数据  
                    int length = ClientSocket.Receive(SocketResult);
                    if (length < 1)
                        break;
                    if (!ClientSocket.Connected)
                        break;
                    string strMsg = System.Text.Encoding.ASCII.GetString(SocketResult, 0, length);
                    string[] values = strMsg.Split(',');
                    int idx = -1;
                    int idxt = -1;
                    string BDEKEN = "";
                    string bdevalue = "";
                    long ticks = 0;
                    
                    foreach (string value in values)
                    {
                        idx = value.IndexOf(":");
                        idxt = value.IndexOf(";");
                        if (idx <= 0)
                            continue;
                        if (idxt <= 0)
                            continue;
                        BDEKEN = value.Substring(0, idx);
                        bdevalue = value.Substring(idx + 1,idxt-idx-1);
                       
                        if (bdevalue.Contains("-"))
                            continue;
                        ticks = long.Parse(value.Substring(idxt + 1));
                        if (lastticks > ticks)
                            continue;
                        lastticks = ticks;
                        foreach (KeyValuePair<string, object> kp in MachinesLib)
                        {
                            DataTable TBAM06 = null;
                            if (kp.Value is UIAM)
                            {
                                TBAM06 = ((UIAM)kp.Value).TMV.TBAM06;
                            }
                            if (kp.Value is VAMSTAMM)
                            {
                                TBAM06 = ((VAMSTAMM)kp.Value).TBAM06;
                            }
                            var qAM = from am06 in TBAM06.AsEnumerable()
                                      where am06["BDEKEN"].ToString().Trim() == BDEKEN
                                      select am06;
                            foreach (DataRow row in qAM)
                            {
                                row["AMEWERTNR"] = bdevalue;
                                if (kp.Value is UIAM)
                                {
                                    UIAM uiam = ((UIAM)kp.Value);
                                    uiam.Dispatcher.Invoke(new SetFunctionDelegate(SetFunction), new object[] { uiam, BDEKEN, bdevalue });
                                }
                                else
                                {
                                    SetFunction(kp.Value, BDEKEN, bdevalue);
                                }


                            }
                        }
                        idx = -1;
                    }
                }
                catch (Exception ex)
                {
                    LogHelper.error(ex.Message);
                }
            }
        }
        bool InvokeRequired = true;
        protected void SetFunction(object uiam, string BDEKEN, string vu)
        {
            if (uiam is UIAM)
            {
                LogHelper.info(vu);
                switch (BDEKEN.Substring(7))
                {
                    case "1":
                        ((UIAM)uiam).VU0 = vu;
                        break;
                    case "2":
                        ((UIAM)uiam).VU1 = vu;
                        break;
                    case "3":
                        ((UIAM)uiam).VU2 = vu;
                        break;
                    case "4":
                        ((UIAM)uiam).VU3 = vu;
                        break;
                    case "5":
                        ((UIAM)uiam).VU4 = vu;
                        break;
                    case "6":
                        ((UIAM)uiam).VU5 = vu;
                        break;
                    case "7":
                        ((UIAM)uiam).VU6 = vu;
                        break;
                    case "8":
                        ((UIAM)uiam).VU7 = vu;
                        break;
                    case "9":
                        ((UIAM)uiam).VU8 = vu;
                        break;
                }
            }
            if (uiam is VAMSTAMM)
            {

                switch (BDEKEN.Substring(7))
                {
                    case "1":
                        ((VAMSTAMM)uiam).VU0 = vu;
                        break;
                    case "2":
                        ((VAMSTAMM)uiam).VU1 = vu;
                        break;
                    case "3":
                        ((VAMSTAMM)uiam).VU2 = vu;
                        break;
                    case "4":
                        ((VAMSTAMM)uiam).VU3 = vu;
                        break;
                    case "5":
                        ((VAMSTAMM)uiam).VU4 = vu;
                        break;
                    case "6":
                        ((VAMSTAMM)uiam).VU5 = vu;
                        break;
                    case "7":
                        ((VAMSTAMM)uiam).VU6 = vu;
                        break;
                    case "8":
                        ((VAMSTAMM)uiam).VU7 = vu;
                        break;
                    case "9":
                        ((VAMSTAMM)uiam).VU8 = vu;
                        break;
                }
            }

        }
        #endregion

        #region 03向客户端发送消息
        /// <summary>
        /// 向客户端发送消息
        /// </summary>
        /// <param name="strMsg"></param>

        public void Register(string command, object DataSend, object uiam)
        {
            if (!ClientSocket.Connected)
                return;
            DataSet SResult = VAME.QAME07((string)DataSend);
            foreach (DataRow row in SResult.Tables[0].Rows)
            {
                row["DES"] = Helper.GetGB2312Value(row["AMEBEZ"].ToString());
            }
            if (uiam is UIAM)
            {
                ((UIAM)uiam).TMV.TBAM06 = SResult.Tables[0].Copy();
            }
            if (uiam is VAMSTAMM)
            {
                ((VAMSTAMM)uiam).TBAM06 = SResult.Tables[0].Copy();
            }
            string sendMessage = command + ":" + DataSend;
            byte[] bytes = null;
            bytes = Encoding.ASCII.GetBytes(sendMessage);
            if (bytes == null)
                return;
            ClientSocket.Send(bytes);//发送到机台命令
            Thread.Sleep(300);
        }
        public void UNRegister(string command, object DataSend)
        {
            if (!ClientSocket.Connected)
                return;
            string sendMessage = command + ":" + DataSend;
            byte[] bytes = null;
            bytes = Encoding.ASCII.GetBytes(sendMessage);
            if (bytes == null)
                return;
            ClientSocket.Send(bytes);//发送到机台命令
            Thread.Sleep(300);
        }
        #endregion
        #region 06关闭与客户端连接
        /// <summary>
        /// 关闭与客户端连接
        /// </summary>
        public void CloseConnection()
        {
            try
            {
                receiveThread.Abort();
                isRec = false;
                if (ClientSocket.Connected)
                {
                    ClientSocket.Shutdown(SocketShutdown.Both);
                }
                ClientSocket.Close();
            }
            catch (Exception ex)
            {
                LogHelper.error(ex.Message);
            }

        }
        #endregion
    }
}
